package com.stgy.lease.common.config;

import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.SetBucketPolicyArgs;
import io.minio.errors.*;
import lombok.Data;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;


/**
 * ClassName:MinioConfig
 * Package:com.example.demo01minio.config
 * Description:
 *
 * @Author:helei
 * @Create:2024/8/27 - 10:28
 */
//当前类对象注入到容器时，或者在其他的组件类中通过@EnableCConfigurationProperties注解指定了当前配置常量类 不会保存
@ConfigurationProperties(prefix = "minio")
@Data
@Configuration
public class MinioConfig implements InitializingBean {
    //自动按照属性名匹配
    private String endpoint;// http://192.168.144.128:9000
    private String accessKey;//: minioadmin
    private String secretKey;//: minioadmin
    private String bucket;//: stgy
    private String module;//: image
    private List<String> mediaTypes;//:

    //类的静态属性值 默认为null
    //当容器给当前类的对象成员属性值设置成功以后，可以获取成员属性值设置给静态属性
    //以后希望使用类.属性名获取属性值使用
    public static String ENDPOINT;// http://192.168.144.128:9000
    public static String ACCESS_KEY;//: minioadmin
    public static String SECRET_KEY;//: minioadmin
    public static String BUCKET;//: stgy
    public static String MODULE;//: image
    public static List<String> MEDIA_TYPES;//:

    //InitializingBean是spring提供的，只要组件类实现了该接口
    //当前类的对象初始化以后，成员属性值初始化以后，afterPropertiesSet就会被调用
    @Override
    public void afterPropertiesSet() throws Exception {
        ENDPOINT = this.endpoint;
        ACCESS_KEY = this.accessKey;
        SECRET_KEY = this.secretKey;
        BUCKET = this.bucket;
        MODULE = this.module;
        MEDIA_TYPES = this.mediaTypes;
    }

    @Bean
    public MinioClient getMinioClient() throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        String bucket = MinioConfig.BUCKET;
        //Builder构建者设计模式
        MinioClient client = MinioClient.builder()
                .credentials(MinioConfig.ACCESS_KEY, MinioConfig.SECRET_KEY)
                .endpoint(MinioConfig.ENDPOINT)
                .build();

        boolean exists = client.bucketExists(BucketExistsArgs.builder()
                .bucket(bucket)
                .build());
        if (!exists) {
            //桶不存在，创建桶设置权限
            client.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucket)
                    .build());

            String policyJson = "{\n" +
                    "                        \"Version\": \"2012-10-17\",\n" +
                    "                        \"Statement\": [\n" +
                    "                            {\n" +
                    "                                \"Effect\": \"Allow\",\n" +
                    "                                \"Principal\": {\n" +
                    "                                    \"AWS\": [\n" +
                    "                                        \"*\"\n" +
                    "                                    ]\n" +
                    "                                },\n" +
                    "                                \"Action\": [\n" +
                    "                                    \"s3:GetBucketLocation\",\n" +
                    "                                    \"s3:ListBucket\",\n" +
                    "                                    \"s3:ListBucketMultipartUploads\"\n" +
                    "                                ],\n" +
                    "                                \"Resource\": [\n" +
                    "                                    \"arn:aws:s3:::" + bucket + "\"\n" +
                    "                                ]\n" +
                    "                            },\n" +
                    "                            {\n" +
                    "                                \"Effect\": \"Allow\",\n" +
                    "                                \"Principal\": {\n" +
                    "                                    \"AWS\": [\n" +
                    "                                        \"*\"\n" +
                    "                                    ]\n" +
                    "                                },\n" +
                    "                                \"Action\": [\n" +
                    "                                    \"s3:AbortMultipartUpload\",\n" +
                    "                                    \"s3:DeleteObject\",\n" +
                    "                                    \"s3:GetObject\",\n" +
                    "                                     \"s3:ListMultipartUploadParts\",\n" +
                    "                                    \"s3:PutObject\"\n" +
                    "                                ],\n" +
                    "                                \"Resource\": [\n" +
                    "                                    \"arn:aws:s3:::" + bucket + "/*\"\n" +
                    "                                ]\n" +
                    "                            }\n" +
                    "                        ]\n" +
                    "                    }";
            //给桶设置全选
            client.setBucketPolicy(SetBucketPolicyArgs.builder()
                    .bucket(bucket)
                    .config(policyJson)
                    .build());
        }
        return client;
    }
}
